import 'package:cmd_myapp_demo/components/My_App.dart';
import 'package:cmd_myapp_demo/components/my_home_page.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp(child: _LoadDemo()));
}

class _SpinKitRippleDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return const MyHomePage(title: Text("自定义弹窗"), child: _SpinKitRipple(color: Colors.deepPurple,));
  }
}

class _SpinKitRipple extends StatefulWidget {
  const _SpinKitRipple(
      {super.key,
      this.color = Colors.black54,
      this.size = 50.0,
      this.borderWidth = 6.0, this.itemBuilder,
      this.duration = const Duration(milliseconds: 2000)})
      : assert(color != null),
        assert(size != null),
        assert(borderWidth != null);

  final Color color;
  final double size;
  final double borderWidth;
  final IndexedWidgetBuilder? itemBuilder;
  final Duration duration;

  @override
  _SpinKitRippleState createState() => _SpinKitRippleState();
}

class _SpinKitRippleState extends State<_SpinKitRipple> with SingleTickerProviderStateMixin{

  late AnimationController _controller;
  late Animation<double> _animation1,_animation2;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: widget.duration,
      vsync: this
    )..repeat();

    _animation1 = Tween(begin: 0.0, end: 1.0).animate(
      CurvedAnimation(parent: _controller, curve: const Interval(0.0, 0.75, curve: Curves.linear))
    )..addListener(() => setState(() => <String, void>{}));

    _animation2 = Tween(begin: 0.0, end: 1.0).animate(
      CurvedAnimation(parent: _controller, curve: const Interval(0.25, 1.0, curve: Curves.linear))
    )..addListener(() => setState(() => <String, void>{}));
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        Opacity(
          opacity: 1.0 - _animation1.value,
          child: Transform.scale(
            scale: _animation1.value,
            child: _itemBuilder(0),
          ),
        ),
        Opacity(
          opacity: 1.0 - _animation2.value,
          child: Transform.scale(
            scale: _animation2.value,
            child: _itemBuilder(1),
          ),
        )
      ],
    );
  }

  Widget _itemBuilder(int index) {
    return SizedBox.fromSize(
      size: Size.square(widget.size),
      child: widget.itemBuilder != null
        ? widget.itemBuilder!(context, index)
          : DecoratedBox(
        decoration: BoxDecoration(
          shape: BoxShape.circle,
          border: Border.all(
            color: widget.color,
            width: widget.borderWidth
          )
        ),
      )
    );
  }
}

class _LoadDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MyHomePage(title: const Text("加载框"), child: _LoadingPage());
  }
}

class _LoadingPage extends StatefulWidget {
  @override
  _LoadingPageState createState() => _LoadingPageState();
}

class _LoadingPageState extends State<_LoadingPage> {
  bool _loading = false;

  Future<void> _onRefresh() async {
    setState(() {
      _loading = !_loading;
    });

    // 模拟操作
    await Future.delayed(const Duration(seconds: 5), () {
      setState(() {
        _loading = !_loading;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return _ProgressDialog(
      isLoading: _loading,
      message: "正在加载...",
      alpha: 0.35,
      child: Center(
        child: ElevatedButton(
          onPressed: _onRefresh,
          child: const Text("显示加载动画"),
        ),
      ),
    );
  }
}

class _ProgressDialog extends StatelessWidget {

  const _ProgressDialog({
    super.key,
    required this.isLoading,
    this.message,
    this.progress = const _SpinKitRipple(color: Colors.white, size: 60.0,),
    this.alpha = 0.5,
    this.textColor = Colors.white,
    required this.child});

  // 子布局
  final Widget child;
  // 是否加载中
  final bool isLoading;
  // 加载信息
  final String? message;
  // 加载中动画
  final Widget progress;
  // 透明度
  final double alpha;
  // 字体颜色
  final Color textColor;

  @override
  Widget build(BuildContext context) {
    List<Widget> widgetList = [];
    widgetList.add(child);

    // 布局加载组件
    if (isLoading) {
      Widget layoutProgress;
      if (message == null) {
        layoutProgress = Center(
          child: progress,
        );
      } else {
        // 有加载信息
        layoutProgress = Center(
          child: Container(
            padding: const EdgeInsets.all(20.0),
            decoration: BoxDecoration(
              color: Colors.black87,
              borderRadius: BorderRadius.circular(4.0)
            ),
            child: Column(
              // 水平垂直居中
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.center,
              mainAxisSize: MainAxisSize.min,
              children: <Widget>[
                progress,
                Container(
                  padding: const EdgeInsets.fromLTRB(10.0, 10.0, 10.0, 0),
                  child: Text(
                    message!,
                    style: TextStyle(color: textColor, fontSize: 16.0),
                  ),
                )
              ],
            ),
          ),
        );
      }

      widgetList.add(
        Opacity(
          opacity: alpha,
          child: const ModalBarrier(
            color: Colors.black87,
          ),
        )
      );
      widgetList.add(layoutProgress);
    }

    return Stack(
      children: widgetList,
    );
  }
}

